var slotInfos = new Array();

function filter_this_array(toDelete, source) {
    var result = new Array();
    if (toDelete.length) {
        for (var i = 0; i < source.length; i++) {
            if (!in_array(in_array(i, toDelete))) {
                result.push(source[i]);
            }
        }
    } else {
        result = source;
    }
    return result;
}

function thisSlotHasNoContact(startTime, endTime) {
    for (var i = 0; i < slotInfos.length; i++) {
        if (startTime >= slotInfos[i]['startTime'] && startTime <= slotInfos[i]['endTime'] || endTime >= slotInfos[i]['startTime'] && endTime <= slotInfos[i]['endTime']) {
            return false;
        }
    }
    return true;
}

function getSlotContact(startTime, endTime) {
    var slotContacts = new Array();
    for (var i = 0; i < slotInfos.length; i++) {
        if (startTime >= slotInfos[i]['startTime'] && startTime <= slotInfos[i]['endTime'] || endTime >= slotInfos[i]['startTime'] && endTime <= slotInfos[i]['endTime']) {
            slotContacts.push(i);
        }
    }
    return slotContacts;
}

function getRequiredInterval(slotsInContacts, startTime, endTime) {
    if (slotsInContacts.length == 1) {
        var slotInContact = slotInfos[slotsInContacts[0]];
        if (startTime < slotInContact['startTime']) {
            slotInfos[slotsInContacts[0]] = {
                'startTime': startTime - (3600 * 24 * 7 * 1000),
                'endTime': slotInContact['endTime']
            }
            return{
                'startTime': startTime - (3600 * 24 * 7 * 1000),
                'endTime': slotInContact['startTime']
            }
        } else if (endTime > slotInContact['endTime']) {
            slotInfos[slotsInContacts[0]] = {
                'startTime': slotInContact['startTime'],
                'endTime': endTime + (3600 * 24 * 7 * 1000)
            }
            return{
                'startTime': slotInContact['endTime'],
                'endTime': endTime + (3600 * 24 * 7 * 1000)
            }
        }
    } else if (slotsInContacts.length == 2) {
        // Create fusion with the 2 slots
        if (slotInfos[slotsInContacts[0]]['startTime'] < slotInfos[slotsInContacts[1]]['startTime']) {
            lowerSlot = slotInfos[slotsInContacts[0]];
            higherSlot = slotInfos[slotsInContacts[1]];
        } else {
            lowerSlot = slotInfos[slotsInContacts[1]];
            higherSlot = slotInfos[slotsInContacts[0]];
        }
        slotInfos.push({
            'startTime': lowerSlot['startTime'],
            'endTime': higherSlot['endTime']
        });
        delete slotInfos[slotsInContacts[0]];
        delete slotInfos[slotsInContacts[1]];
        return {
            'startTime': lowerSlot['endTime'],
            'endTime': higherSlot['startTime']
        };
    }
    return {
        'startTime': 0,
        'endTime': 0
    };
}

function addThisSlot(startTime, endTime) {
    if (slotInfos.length == 0) {
        var now = new Date().getTime();
        slotInfos.push({
            'startTime': now - (3600 * 24 * 7 * 1000),
            'endTime': now + (3600 * 24 * 14 * 1000)
        });
        return 0;
    }
    return {
        'startTime': startTime,
        'endTime': endTime
    }
}


function bIsAlreadyLoaded(startTime, endTime) {
    for (var i = 0; i < slotInfos.length; i++) {
        if (startTime >= slotInfos[i]['startTime'] && startTime <= slotInfos[i]['endTime'] && endTime >= slotInfos[i]['startTime'] && endTime <= slotInfos[i]['endTime']) {
            return true;
        }
    }
    return false;
}

function initCalendarCache(jsonAgendaPrestations) {
    window.calendarCache = new Array();
    window.calendarCache['is_syncing'] = false;
    window.calendarCache['timer'] = false;
    window.calendarCache['displayType'] = 'std';
    window.calendarCache['options'] = {'defaultFreeBusy': {'free': true}};
    window.calendarCache['presta'] = new Array();
    window.calendarCache['slot'] = new Array();
    window.calendarCache['web'] = new Array();
    window.calendarCache['note'] = {};
    window.calendarCache['ComboPresta'] = dataComboPresta['combo'];
    window.calendarCache['ComboPrestaInfos'] = dataComboPresta['infos'];
    window.calendarCache['AgendaPrestations'] = jsonAgendaPrestations;
    window.getAllSlots = true;
}


function get_cache_infos(startTime, endTime, web, callbackFunction) {
    window.calendarCache['startTime'] = startTime;
    window.calendarCache['endTime'] = endTime;
    slot = addThisSlot(startTime, endTime);
    if ((window.localRefresh == undefined || window.localRefresh == false)) {
        // slot is array
        var ajaxUrl = WEBROOT + '/FastService/EventList.php';
        var post_array = {};
        post_array['start_time'] = startTime;
        post_array['end_time'] = endTime;
        post_array['agendas'] = window.agendaIdArray;
        post_array['get_all_slots'] = window.getAllSlots;
        ajax(ajaxUrl, post_array, function(data) {
            result = json_decode(data);
            window.getAllSlots = false;
            if (result != null) {
                window.calendarCache['presta'] = result['presta'];
                window.calendarCache['note'] = result['note'];
                window.calendarCache['web'] = result['web'];
                window.calendarCache['slot'] = result['slot'];
                //add_replace_events(result['web'], 'web');
                //add_replace_events(result['slot'], 'slot');
                /*add_replace_events(result['presta'], 'presta');
                 add_replace_events(result['web'], 'web');
                 add_replace_events(result['slot'], 'slot');*/
            }
            callbackFunction(fetch_cache(startTime, endTime));
        });
    } else {
        window.localRefresh = false;
        callbackFunction(fetch_cache(startTime, endTime));
    }
}


function add_events(events, key) {
    window.calendarCache[key] = array_merge(window.calendarCache[key], events);
}

function remove_events(calEvents) {
    if (calEvents != undefined && calEvents.length) {
        index_to_delete = -1;
        eventType = calEvents[0].event_type;
        for (i = 0; i < calEvents.length; i++) {
            calEvent = calEvents[i];
            for (j = 0; j < window.calendarCache[eventType].length; j++) {
                if (window.calendarCache[eventType][j].id.toString() == calEvent.id.toString()) {
                    index_to_delete = j;
                }
            }
        }
        if (index_to_delete > -1) {
            window.calendarCache[eventType].splice(index_to_delete, 1);
        }
    }
}

function remove_event(calEvent) {
    var index_to_delete = -1;
    var eventType = calEvent.event_type;
    var occurency_to_delete = '';
    if (calEvent.occurency != undefined && calEvent.occurency != 'original') {
        if (calEvent.slots_to_delete == 'only_this') {
            occurency_to_delete = calEvent.occurency + ';';
        } else if (calEvent['slots_to_delete'] == 'this_and_further') {
            occurency_to_delete = calEvent.occurency + ';n;';
        }
    }
    for (i = 0; i < window.calendarCache[eventType].length; i++) {
        if (window.calendarCache[eventType][i].id.toString() == calEvent.id.toString()) {
            if (occurency_to_delete.length) {
                window.calendarCache[eventType][i].deleted_occurencies = window.calendarCache[eventType][i].deleted_occurencies + occurency_to_delete + ';';
            } else {
                index_to_delete = i;
            }
        }
    }
    if (index_to_delete > -1) {
        window.calendarCache[eventType].splice(index_to_delete, 1);
    }

}

function move_event(calEvent) {
    eventType = calEvent.event_type;
    for (i = 0; i < window.calendarCache[eventType].length; i++) {
        if (window.calendarCache[eventType][i].id.toString() == calEvent.id.toString()) {
            if ((calEvent.occurency != undefined && calEvent.occurency == 'original') || calEvent.event_type == 'presta') {
                window.calendarCache[eventType][i].slot_day = calEvent.slot_day;
            }
            window.calendarCache[eventType][i].slot_start = calEvent.slot_start;
            window.calendarCache[eventType][i].slot_end = calEvent.slot_end;
            window.calendarCache[eventType][i].agenda_id = calEvent.agenda_id;
        }
    }
}

function resize_slot(calEvent) {
    eventType = calEvent.event_type;
    for (i = 0; i < window.calendarCache[eventType].length; i++) {
        if (window.calendarCache[eventType][i].id.toString() == calEvent.id.toString()) {
            window.calendarCache[eventType][i].slot_start = calEvent.slot_start;
            window.calendarCache[eventType][i].slot_end = calEvent.slot_end;
        }
    }
}

function replace_client_and_name_id(event_id, client_id, nom_client) {
    for (i = 0; i < window.calendarCache['presta'].length; i++) {
        if (window.calendarCache['presta'][i].id.toString() == event_id) {
            window.calendarCache['presta'][i].client_id = client_id;
            window.calendarCache['presta'][i].nom_client = nom_client;
        }
    }
}

function add_replace_events(calEvents) {
    if (calEvents.length) {
        eventType = calEvents[0].event_type;
        for (i = 0; i < calEvents.length; i++) {
            calEvent = calEvents[i];
            var bReplace = false;
            for (j = 0; j < window.calendarCache[eventType].length; j++) {
                if (window.calendarCache[eventType][j].id.toString() == calEvent.id.toString()) {
                    window.calendarCache[eventType][j] = calEvent;
                    bReplace = true;
                }
            }
            if (!bReplace) {
                window.calendarCache[eventType].push(calEvent);
            }
        }
    }
}

function add_replace_event(calEvent) {
    var bReplace = false;
    eventType = calEvent.event_type;
    for (i = 0; i < window.calendarCache[eventType].length; i++) {
        if (window.calendarCache[eventType][i].id.toString() == calEvent.id.toString()) {
            window.calendarCache[eventType][i] = calEvent;
            bReplace = true;
        }
    }
    if (!bReplace) {
        window.calendarCache[eventType].push(calEvent);
    }
}



function fetch_cache(start, end) {
    // First add events  
    var prestationList = window.calendarCache["ComboPrestaInfos"];
    var eventList = new Array();
    var agendaIdArrayFlipped = array_flip(window.agendaIdArray);

    var slots = new Array();
    var freebusys = new Array();
    if (window.calendarCache['displayType'] == 'std') {
        // Then, add slots and eventually repeat them
        if (window.calendarCache['slot'] != undefined) {
            for (i = 0; i < window.calendarCache['slot'].length; i++) {
                event = window.calendarCache['slot'][i];
                slots = enable_repeat(event, slots, agendaIdArrayFlipped, start, end, false, true);
            }
        }
        if (slots.length) {
            eventList = array_merge(eventList, slots);
        }
    }
    if (window.calendarCache['web'] != undefined) {
        for (i = 0; i < window.calendarCache['web'].length; i++) {
            var event = window.calendarCache['web'][i];
            freebusys = enable_repeat(event, freebusys, agendaIdArrayFlipped, start, end, false, true);
        }
    }
    if (freebusys.length) {
        eventList = array_merge(eventList, freebusys);
    }
    /////////////////////////
    // Common filtering
    /////////////////////////
    window.events = crossfilter(eventList);
    window.eventsByDate = window.events.dimension(function(d) {
        return d.start;
    }),
            window.eventsByAgenda = window.events.dimension(function(d) {
        return d.agenda_id;
    });

    /* window.eventsByDate.filter([start, end]).top(Infinity);
     var eventArray = new Array();
     for (i = 0; i < window.agendaIdArray.length; i++) {
     var eventsByAgendaArray = window.eventsByAgenda.filter(window.agendaIdArray[i]).top(Infinity);
     eventArray = array_merge(eventArray, eventsByAgendaArray);
     }*/
    // Events are by nature filtered correctly

    eventArray = freebusys;
    if (window.calendarCache['displayType'] == 'std') {
        eventArray = array_merge(freebusys, window.calendarCache['presta']);
        eventArray = array_merge(eventArray, eventList);
    }
    // Now split event between web and standard events
    ///////////////////////////////////////////////////
    var eventAndSlotArray = new Array();
    var freebusyArray = new Array();
    // Now display correct agenda id
    for (var i = 0; i < eventArray.length; i++) {
        // Calculate stop and start for prestations
        eventArray[i].start = (eventArray[i].slot_start + eventArray[i].slot_day) * 1000;
        eventArray[i].end = (eventArray[i].slot_end + eventArray[i].slot_day) * 1000;

        var position = getPositionFromAgendaId(eventArray[i].agenda_id);
        if (position != -1) {
            eventArray[i].userId = position;
        }
        if (window.calendarCache['displayType'] == 'std') {
            if (eventArray[i].event_type == 'web') {
                freebusyArray.push(eventArray[i]);
            } else {
                if (eventArray[i].event_type == 'presta' && eventArray[i].nom_client != undefined) {
                    if (!strstr(eventArray[i].title, '<br/>')) {
                        eventArray[i].title = eventArray[i].title + '<br/><i>' + eventArray[i].nom_client + ' ' + eventArray[i].prenom_client + '</i>';
                    }
                } else if (eventArray[i].event_type == 'presta' && eventArray[i].nom_client == undefined && eventArray[i].prenom_client == undefined) {
                    // Delete event if client not exists
                    addToLocalStore('DELETE_EVENT', eventArray[i]);
                }
                eventAndSlotArray.push(eventArray[i]);
            }
            // currentPrestation['name'];
            //      currentPrestation['color'];
            //      (currentPrestation['duree']*60);
        }
    }

    // Split events if std view
    if (window.calendarCache['displayType'] == 'std') {
        return {
            'options': window.calendarCache['options'],
            'events': eventAndSlotArray,
            'freebusys': freebusyArray
        };
    }
    return {
        'options': window.calendarCache['options'],
        'events': eventArray
    };
}



function getPositionFromAgendaId(agenda_id) {
    for (var i = 0; i < window.agendaIdArray.length; i++) {
        if (agenda_id == window.agendaIdArray[i]) {
            return i;
        }
    }
    return -1;
}
